import dayjs from 'dayjs';
import { getBleSleepData, getBleSportData, getBleLaserData, getBleHeartData, getBleBloodData } from '~/utils/ble/application';
import { getDeviceWriteInfo, updateAllData, updateStatus } from '~/api/deviceApi'
import { deviceStore, userStore } from '~/store';
import { applyBloodDevice, } from '~/utils/deviceMenues';


let sleepDataCache: any = []; // 缓存当天睡眠数据包
let currentDate: any = null; // 开始日期
let endDate: any = null;//结束日期
let dateResult: any = null; // 保存服务器计算的日期区间信息
let laserDayData: any[] = [];   // 每天激光数据缓存
let hrDayData: Record<number, number> = {}; // 每天心率缓存，key=索引(96个点)，value=心率
let bpDayData: any[] = []; // 缓存当天血压数据
let allData: any = {
    sleepData: [],
    sportData: [],
    laserData: [],
    heartRateData: {},
    bloodPressureData: []
}
let taskResolver: ((status: boolean) => void) | null = null;

const updateDataStatus = (type, status,) => {
    const { connectDevice } = deviceStore.device
    updateStatus({ type, status, device_sn: connectDevice.device_sn })
}
// 计算与服务器相差天数
function getDateDiffInfo(serverDate) {
    const { Y, m, d } = serverDate;
    const target = dayjs(`${Y}-${m}-${d}`);
    const now = dayjs();
    let diff = now.diff(target, 'day');
    const reCalculated = target.add(diff, 'day');
    return {
        diffDays: diff,
        targetDate: target.format('YYYY-MM-DD'),
        reCalculatedDate: reCalculated.format('YYYY-MM-DD'),
    };
}

export const getDeviceDataHead = (callBack?: (status: boolean) => void) => {
    // 保存外部回调
    if (callBack) {
        taskResolver = callBack;
    }
    const { connectDevice } = deviceStore.device
    getDeviceWriteInfo({ device_sn: connectDevice.device_sn }).then(res => {
        if (res.status !== 1) {
            callBack?.(false)
            return
        }
        deviceStore.onUploadProgress(90)
        dateResult = getDateDiffInfo(res.data.deviceInfo.upload_data_last_date)
        getSportData(dateResult)
    }).catch(() => {
        callBack?.(false)
    })
}

// ------------------- 步数数据 -------------------
const getSportData = (date) => {
    currentDate = dayjs(date.targetDate);
    endDate = dayjs();
    const d = currentDate;
    getBleSportData({
        year: d.year(),
        month: d.month() + 1,
        day: d.date()
    });
}

const requestSportData = (date) => {
    getBleSportData({
        year: date.year(),
        month: date.month() + 1,
        day: date.date(),
    });
};

// ------------------- 激光数据 -------------------
const getLaserData = (date) => {
    currentDate = dayjs(date.targetDate);
    endDate = dayjs();
    const d = currentDate;
    getBleLaserData({
        year: d.year(),
        month: d.month() + 1,
        day: d.date()
    });
}
const requestLaserData = (date) => {
    getBleLaserData({
        year: date.year(),
        month: date.month() + 1,
        day: date.date(),
    });
};

// ------------------- 心率数据 -------------------
const getHeartData = (date) => {
    currentDate = dayjs(date.targetDate);
    endDate = dayjs();
    const d = currentDate;
    getBleHeartData({
        year: d.year(),
        month: d.month() + 1,
        day: d.date()
    });
}

const requestHeartRateData = (date) => {
    getBleHeartData({
        year: date.year(),
        month: date.month() + 1,
        day: date.date(),
    });
};

// ------------------- 血压数据 -------------------
const getBloodData = (date) => {
    currentDate = dayjs(date.targetDate);
    endDate = dayjs();
    const d = currentDate;
    getBleBloodData({
        year: d.year(),
        month: d.month() + 1,
        day: d.date()
    });
}

const requestBloodPressure = (date) => {
    getBleBloodData({
        year: date.year(),
        month: date.month() + 1,
        day: date.date(),
    });
};


// ------------------- 睡眠数据 -------------------
const getSleepData = (date) => {
    currentDate = dayjs(date.targetDate);
    endDate = dayjs();
    sleepDataCache = [];
    const d = currentDate;
    requestSleepData({
        year: d.year(),
        month: d.month() + 1,
        day: d.date()
    });
}

const requestSleepData = (date) => {
    getBleSleepData({
        year: date.year(),
        month: date.month() + 1,
        day: date.date()
    });
}


function mapStage(state) {
    switch (state) {
        case 0: return '清醒状态';
        case 1: return '快速睡眠';
        case 2: return '核心睡眠';
        case 3: return '深度睡眠';
        default: return '未知';
    }
}

// 合并相同时间段的时间参数
const mergeSleepSegments = (segments) => {
    if (!segments.length) return [];
    const merged: any = [];
    let current = { ...segments[0] };
    for (let i = 1; i < segments.length; i++) {
        const next = segments[i];
        if (next.state === current.state && next.start === current.end) {
            current.end = next.end;
        } else {
            merged.push({ ...current });
            current = { ...next };
        }
    }
    merged.push({ ...current });
    return merged;
};


const parseSleepSegments = (rawData, baseDate) => {
    const result: any = [];
    for (let i = 0; i < rawData.length; i++) {
        const [hour, ...statusBytes] = rawData[i];
        if (typeof hour !== 'number' || statusBytes.length !== 6) continue;
        const hourStart = dayjs(`${baseDate} ${String(hour).padStart(2, '0')}:00`);
        for (let j = 0; j < statusBytes.length; j++) {
            const byte = statusBytes[j];
            const high = (byte & 0xf0) >> 4;
            const low = byte & 0x0f;
            const start1 = hourStart.add((j * 2) * 5, 'minute');
            const end1 = start1.add(5, 'minute');
            result.push({
                start: start1.format('YYYY-MM-DD HH:mm'),
                end: end1.format('YYYY-MM-DD HH:mm'),
                state: high,
                stage: mapStage(high)
            });
            const start2 = hourStart.add((j * 2 + 1) * 5, 'minute');
            const end2 = start2.add(5, 'minute');
            result.push({
                start: start2.format('YYYY-MM-DD HH:mm'),
                end: end2.format('YYYY-MM-DD HH:mm'),
                state: low,
                stage: mapStage(low)
            });
        }
    }

    return result;
}




// 开始上传数据给服务器
const uploadData = (): Promise<boolean> => {
    return new Promise((resolve) => {
        const { connectDevice } = deviceStore.device;
        updateAllData({
            device_sn: connectDevice.device_sn,
            bloodPressureData: allData.bloodPressureData.length === 0 ? false : JSON.stringify(allData.bloodPressureData),
            movementData: allData.sportData.length === 0 ? false : JSON.stringify(allData.sportData),
            laserData: allData.laserData.length === 0 ? false : JSON.stringify(allData.laserData),
            HeartRateData: Object.keys(allData.heartRateData).length === 0 ? false : JSON.stringify(allData.heartRateData)
        }).then(res => {
            if (res.status !== 1) {
                resolve(false);
                return;
            }
            deviceStore.onUploadProgress(100);
            updateDataStatus('updateAll', 100);
            resolve(true);
        }).catch(() => {
            resolve(false);
        }).finally(() => {
            allData = {
                sleepData: [],
                sportData: [],
                laserData: [],
                heartRateData: {},
                bloodPressureData: []
            };
        });
    });
};

// 解析硬件数据
export const getHandleBleDataResponse = (type, data) => {
    try {
        switch (type) {
            case 'sport':
                const stepsNum = data.length === 4 ? (data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)) : 0;
                const yStr = currentDate.year().toString();
                const mStr = (currentDate.month() + 1).toString().padStart(2, "0");
                const dStr = currentDate.date().toString().padStart(2, "0");
                const index = Object.keys(allData.sportData).length;
                allData.sportData[index] = {
                    user_id: userStore.me.user_id,
                    y: yStr,
                    m: mStr,
                    d: dStr,
                    steps_num: stepsNum
                };
                currentDate = currentDate.add(1, 'day');
                if (currentDate.isAfter(endDate, 'day')) {
                    updateDataStatus('updateStatus', 30)
                    getLaserData(dateResult) // 开始获取设备治疗数据
                    return;
                }
                requestSportData(currentDate);
                break;
            case 'laser':
                if (data.length === 8) {
                    if (data[7] !== 1) {
                        const startTime = data[0] + ":" + (data[1] < 10 ? "0" + data[1] : data[1]);
                        const t = data[3] ?? 0;
                        const yStr = currentDate.year().toString();
                        const mStr = (currentDate.month() + 1).toString().padStart(2, "0");
                        const dStr = currentDate.date().toString().padStart(2, "0");
                        const item = {
                            start_time: startTime,
                            power_level: data[2].toString(),
                            err_code: parseInt(data[2].toString(16).padStart(2, "0")[0]),
                            time: t,
                            heartRate: data[5],
                            user_id: userStore.me.user_id,
                            course_sn: data[7],
                            y: yStr,
                            m: mStr,
                            d: dStr,
                            [startTime]: t
                        };
                        if (!laserDayData.find(i => i.start_time === item.start_time)) {
                            laserDayData.push(item);
                        }
                    }
                } else if (data.length === 1 && data[0] === 4) {
                    // 一天的数据结束
                    if (laserDayData.length) {
                        const yStr = currentDate.year().toString();
                        const mStr = (currentDate.month() + 1).toString().padStart(2, "0");
                        const dStr = currentDate.date().toString().padStart(2, "0");
                        allData.laserData.push({
                            user_id: userStore.me.user_id,
                            y: yStr,
                            m: mStr,
                            d: dStr,
                            type: 0,
                            data: [...laserDayData]
                        });
                    }

                    laserDayData = [];
                    currentDate = currentDate.add(1, 'day');
                    if (currentDate.isAfter(endDate, 'day')) {
                        const { connectDevice } = deviceStore.device
                        if (applyBloodDevice.indexOf(connectDevice.device_code) !== -1) {
                            // 获取血压数据
                            updateDataStatus('updateStatus', 60)
                            getBloodData(dateResult)
                        } else {
                            // 获取心率数据
                            updateDataStatus('updateStatus', 60)
                            getHeartData(dateResult)
                        }
                        return;
                    }
                    requestLaserData(currentDate);
                }
                break;
            case 'heart':
                if (data.length === 1 && data[0] === 4) {
                    if (Object.keys(hrDayData).length) {
                        const yStr = currentDate.year().toString();
                        const mStr = (currentDate.month() + 1).toString().padStart(2, "0");
                        const dStr = currentDate.date().toString().padStart(2, "0");
                        const index = Object.keys(allData.heartRateData).length;
                        allData.heartRateData[index] = {
                            user_id: userStore.me.user_id,
                            y: yStr,
                            m: mStr,
                            d: dStr,
                            data: JSON.stringify(hrDayData)  // 🔹 字符串化
                        };
                    }
                    // 清空缓存，推进到下一天
                    hrDayData = {};
                    currentDate = currentDate.add(1, "day");
                    if (currentDate.isAfter(endDate, "day")) {
                        updateDataStatus('updateStatus', 90)
                        uploadData().then(status => {
                            taskResolver?.(status); // 上传完成后通知外部
                            taskResolver = null;
                        });
                        return;
                    }
                    requestHeartRateData(currentDate);

                } else if (data.length === 6) {
                    // 自动心率（过滤手动）
                    if (data[6] === 1) return;

                    let heartRateIndex = (data[0] * 60 + data[1]) / 15; // 分钟索引
                    hrDayData[heartRateIndex] = data[3];
                }
                break
            case 'blood':
                if (data.length === 1 && data[0] === 4) {
                    bpDayData.forEach(record => {
                        allData.bloodPressureData.push(record);
                    });
                    bpDayData = [];
                    currentDate = currentDate.add(1, "day");
                    if (currentDate.isAfter(endDate, "day")) {
                        updateDataStatus('updateStatus', 90)
                        uploadData().then(status => {
                            taskResolver?.(status); // 上传完成后通知外部
                            taskResolver = null;
                        });
                        return;
                    }
                    requestBloodPressure(currentDate);

                } else if (data.length === 6) {
                    // 每条血压数据
                    const yStr = currentDate.year().toString();
                    const mStr = (currentDate.month() + 1).toString().padStart(2, "0");
                    const dStr = currentDate.date().toString().padStart(2, "0");
                    const timeStr = `${data[0] < 10 ? "0" + data[0] : data[0]}:${data[1] < 10 ? "0" + data[1] : data[1]}`;
                    bpDayData.push({
                        y: yStr,
                        m: mStr,
                        d: dStr,
                        time: timeStr,
                        systolic: data[2],
                        diastole: data[3],
                        heart_rate: data[4],
                        type: data[5]
                    });
                }
                break
            case 'sleep':
                const isFinished = data.length === 1 && data[0] === 4;
                if (isFinished) {
                    const baseDate = currentDate.format('YYYY-MM-DD');
                    const parsed = parseSleepSegments(sleepDataCache, baseDate);
                    const merged = mergeSleepSegments(parsed);
                    const dateObj = dayjs(baseDate);
                    const year = dateObj.year();
                    const month = dateObj.month() + 1;
                    const day = dateObj.date();
                    const dailyData = {
                        y: year,
                        m: month,
                        d: day,
                        data: merged
                    };
                    allData.sleepData.push(dailyData);
                    sleepDataCache = [];
                    currentDate = currentDate.add(1, 'day');
                    if (currentDate.isAfter(endDate, 'day')) {
                        updateDataStatus('updateStatus', 90)
                        uploadData().then(status => {
                            taskResolver?.(status); // 上传完成后通知外部
                            taskResolver = null;
                        });
                        return;
                    }
                    requestSleepData(currentDate);
                } else {
                    sleepDataCache.push(data);
                }
                break;
            default:
                break;
        }
    } catch (error) {
        console.error("解析设备数据出错：", error);
    }
};